package cn.com.shopec.erp.common.orm;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;

import cn.com.shopec.erp.common.page.PageFinder;

public interface IHibernateEntityDao<T> {

    public Object saveObject(Object o) throws Exception;

    /**
     * 保存对象.
     * 
     * @throws Exception
     */
    public T save(T object) throws Exception;

    /**
     * 修改对象
     * 
     * @param o
     * @return
     */
    public T update(T object) throws Exception;

    /**
     * 删除对象.
     * 
     * @throws Exception
     */
    public boolean remove(T object) throws Exception;

    /**
     * 根据ID移除对象.
     * 
     * @throws Exception
     */
    public boolean removeById(Serializable id) throws Exception;

    /**
     * 获取全部对象
     * 
     * @return
     * @throws Exception
     */
    public List<T> getAll() throws Exception;

    /**
     * 获取全部对象带排序
     * 
     * @param orderBy
     *            　 排序字段(属性)
     * @param isAsc
     *            是否升序
     * @return
     * @throws Exception
     */
    public List<T> getAll(String orderBy, boolean isAsc) throws Exception;

    /**
     * 根据ID获取对象. 不带级联查询
     * 
     * @param id
     *            对象ID
     * @return 持久化对象
     */
    public T getById(Serializable id) throws Exception;

    /**
     * 根据ID获取对象. 不带级联查询
     * 
     * @param id
     *            对象ID
     * @param isLock
     *            是否锁定，使用LockMode.UPGRADE(锁定后不允许事物修改)
     * @return 持久化对象
     */
    public T getById(Serializable id, boolean isLock) throws Exception;

    /**
     * 根据属性名和属性值查询单个对象
     * 
     * @param propertyName
     * @param value
     * @return
     */
    public T findUniqueBy(String propertyName, Object value);

    /**
     * 按HQL方式进行分页查询
     * 
     * @param toPage
     *            跳转页号
     * @param pageSize
     *            每页数量
     * @param hql
     *            查询语句
     * @param values
     *            参数
     * @return
     */
    public PageFinder<T> pagedByHQL(String hql, int toPage, int pageSize, Object... values);

    /**
     * 按hibernate离线查询器进行分页查询
     * 
     * @param detachedCriteria
     *            查询器对象
     * @return
     */
    public PageFinder<T> pagedByCriteria(DetachedCriteria detachedCriteria);

    /**
     * 按hibernate离线查询器进行分页查询
     * 
     * @param detachedCriteria
     *            查询器对象
     * @param startIndex
     *            当前是第几页查询
     * @return
     */
    public PageFinder<T> pagedByCriteria(DetachedCriteria detachedCriteria, int startIndex);

    /**
     * 按hibernate离线查询器进行分页查询
     * 
     * @param detachedCriteria
     *            查询器对象
     * @param pageNo
     *            当前页数
     * @param pageSize
     *            每页数据数
     * @return
     * 
     */
    public PageFinder<T> pagedByCriteria(DetachedCriteria detachedCriteria, int pageNo, int pageSize);

    /**
     * 取得Entity的DetachedCriteria. 可变的Restrictions条件列表
     * 
     * @param criterions
     *            查询条件
     * @return
     */
    public DetachedCriteria createCriteria(Criterion... criterions);

    /**
     * 按hibernate离线查询器进行排序
     * 
     * @param orderBy
     *            排序
     * @param isAsc
     *            是否升序
     * @param criterions
     *            查询条件
     * @return
     */
    public DetachedCriteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions);

    /**
     * 离线查询获取全部对象
     * 
     * @param criteria
     *            查询器对象
     * 
     * @return
     */
    public List<T> findByCriteria(DetachedCriteria criteria);

    /**
     * 根据单个属性和属性值查询
     * 
     * @param propertyName
     *            属性名称
     * @param value
     *            属性值
     * @return 符合条件的对象集
     */
    public List<T> findByProperty(String propertyName, Object value);

    /**
     * 获取全部对象,带排序字段与升降序参数
     * 
     * @param orderBy
     *            排序的属性名
     * @param isAsc
     *            是否升序排列
     * @return 排序后的结果集
     */
    public List<T> getAllByOrder(String orderBy, boolean isAsc);

    /**
     * 生成hibernate查询对象
     * 
     * @param hql
     *            语句字符串
     * @param values
     *            值
     * @return
     */
    public Query createQuery(String hql, Object... values);

    /**
     * 生成hibernate查询对象，支持匿名参数
     * 
     * @param hql
     *            hql语句字符串
     * @param values
     *            参数集合
     * @return Query查询对象
     */
    public Query createQuery(String hql, Map<String, ?> values);

    /**
     * 生成hibernate查询对象(SQL)
     * 
     * @param sql
     *            sql语句字符串
     * @param values
     *            参数集合
     * @return Query查询对象
     */
    public Query createSQLQuery(String sql, Object... values);

    /**
     * 成hibernate查询对象，支持匿名参数(SQL)
     * 
     * @param sql
     *            sql语句字符串
     * @param values
     *            参数集合
     * @return Query查询对象
     */
    public Query createSQLQuery(String sql, Map<String, ?> values);

    /**
     * 根据hql查询
     * 
     * @param values
     *            可变参数
     * 
     */

    public List<T> findByHql(String hql, Object... values);

    /**
     * 根据外置命名查询
     * 
     * @param queryName
     *            查询名称
     * @param values
     *            可变参数
     * @return
     */
    public List<T> findByNameQuery(String queryName, Object... values);

    /**
     * 获得总记录数
     * 
     * @return
     */
    public int getCountByCriteria(DetachedCriteria detachedCriteria);
    
    /** 
     * @Title: getSumByCriteria 
     * @Description: 获得某个字段的值的和
     * @param detachedCriteria
     * @param propertyName
     * @return  
     * @throws 
     */
    public T getSumByCriteria(final DetachedCriteria detachedCriteria, final String propertyName);
    
    /** 
     * @Title: getObjectByHql 
     * @Description: 根据hql，取得一个结果对象
     * @param hql
     * @param values
     * @return  
     * @throws 
     */
    public T getObjectByHql(String hql, Object... values);

    /**
     * 根据属性名和属性值获取实体对象.
     * 
     * @param propertyName
     *            属性名称
     * @param value
     *            属性值
     * @return 实体对象
     */
    public T get(String propertyName, Object value);

}